﻿using JNTApp.Common;
using JNTApp.Model;
using JNTApp.util;
using Sorting.Common;
using Sorting.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Sorting
{
    /// <summary>
    /// SortWindow.xaml 的交互逻辑
    /// </summary>
    public partial class SortWindow : Window
    {

        private static Order order;                 //用来存储查询扫描出来的单子
        private static Distributor distributor;     //存储供应商信息

        public SortWindow()
        {
            InitializeComponent();
        }

        //①如果传了运单号进来
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string cnum = this.txtCnum.Text.Trim();

            if (cnum.Length > 0)
            {
                order = queryForOrder(cnum);
                this.txtMess.Text = "运单号已确认，请在左侧扫码称重...";
            }
            else
            {
                order = new Order();
            }
        }

        //①手动扫描运单号
        private void txtCnum_KeyDown(object sender, KeyEventArgs e)
        {
            string cnum = this.txtCnum.Text.Trim();

            if (e.Key == Key.Enter && cnum.Length > 0)
            {
                order = queryForOrder(cnum);
                this.txtMess.Text = "运单号已确认，请在左侧扫码称重...";
            }
            else
            {
                this.txtMess.Text = "等待扫描运单号...";
                order = new Order();
            }
         }

        //②称重并请求价格
        private void txtSZ_KeyDown(object sender, KeyEventArgs e)
        {
            string sz = this.txtSZ.Text.Trim();
            string cnum = this.txtCnum.Text.Trim();

            try
            {
                if (e.Key == Key.Enter && cnum.Length > 0 && sz.Length > 0 && Convert.ToDecimal(sz) != 0)
                {
                    this.txtMess.Text = "物品重量已获取，请选择下家渠道（默认选择价格最优）...";

                    //通过order信息（目的地、重量、物品特征）+ 重量调用接口查询供应商报价

                    //①
                    //List<Distributor> distributors = doPrice(SortWindow.order.Cdes, Convert.ToDecimal(sz));//计算价格

                    //②
                    Dictionary<string, PriceExcel> priceExcelDics = PriceExcelLoader.priceExcelDic;
                    List<Distributor> distributors = new List<Distributor>();
                    foreach (KeyValuePair<string, PriceExcel> priceExcelDic in priceExcelDics)
                    {
                        //Distributor distributor = doPrice(SortWindow.order.Cdes.Trim(), Convert.ToDecimal(sz), kv.Value.DesDic, kv.Value.PriceDic);
                        Distributor distributor = doPrice(SortWindow.order.Cdes.Trim(), Convert.ToDecimal(sz), priceExcelDic);
                        distributors.Add(distributor);
                    }

                    this.listView.ItemsSource = distributors;
                }
                else
                {
                    this.txtMess.Text = "重量无效，请在左侧称重...";
                    this.listView.ItemsSource = null;
                }
            }
            catch (Exception x) {
                MessageBox.Show(x.Message);
            }
        }

        /// <summary>
        /// 通过目的地计算所有分区运费
        /// </summary>
        private static List<Distributor> doPrice(string des,decimal sz)
        {
            Dictionary<string, DataTable> desDic = ExcelDictionary.desDic;
            Dictionary<string, DataTable> priceDic = ExcelDictionary.priceDic;

            if (desDic != null && priceDic != null)
            {
                try
                {
                    // ①遍历所有分区查找包含目的地的分区名
                    int? count = 0;
                    List<string> fenQus = new List<string>();

                    foreach (KeyValuePair<string, DataTable> kv in desDic)
                    {
                        if (findSheetByDes(kv.Value, des))
                        {
                            count++;
                            fenQus.Add(kv.Key);//包含目的地的分区
                        }
                    }

                    if (count == 0)
                    {
                        MessageBox.Show("没有找到包含该目的地的渠道");
                    }

                    List<Distributor> distributors = new List<Distributor>();
                    foreach (string fenQu in fenQus)
                    {
                        // ②遍历所有分区，根据order查找价格
                        DataTable dt = priceDic[fenQu];
                        distributors.Add(findPriceByWeight(dt, sz));
                    }

                    return distributors;
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                    return null;
                }
            }
            else {
                throw new Exception("解析价格表异常，可能是价格表格式有误");
            }
        }

        /// <summary>
        /// 通过目的地计算所有分区运费
        /// </summary>
        private static Distributor doPrice(string des, decimal sz, KeyValuePair<string, PriceExcel> priceExcelDic)
        {
            string priceExcelName = priceExcelDic.Key;
            Dictionary<string, DataTable> desDic = priceExcelDic.Value.DesDic;
            Dictionary<string, DataTable> priceDic = priceExcelDic.Value.PriceDic;
            foreach (KeyValuePair<string, DataTable> kv in desDic)
            {
                if (findSheetByDes(kv.Value, des))
                {
                    DataTable dt = priceDic[kv.Key];
                    Distributor distributor = findPriceByWeight(dt, sz);
                    distributor.Name = priceExcelName;
                    return distributor;
                }
            }
            return null;
        }

        /// <summary>
        /// 根据目的地搜索分区
        /// </summary>
        /// <param name="dt"></param>
        public static bool findSheetByDes(DataTable dt,string des) {
            DataRow[] rows = dt.Select();
            int? flag = 0;
            for (int i = 0; i < rows.Length; i++)
            {
                if (rows[i][0].ToString().Trim().Equals(des.Trim())) {
                    flag++;
                }
            }
            return flag == 0 ? false : true;
        }

        /// <summary>
        /// 根据重量计算某分区运费
        /// </summary>
        /// <param name="dt"></param>
        public static Distributor findPriceByWeight(DataTable dt, decimal? weight)
        {
            DataRow[] rows = dt.Select();
            Distributor distributor = new Distributor();
            distributor.Flag = 0;

            for (int i = 0; i < rows.Length; i++)
            {

                decimal? start = Convert.ToDecimal(rows[0][0].ToString().Trim().Equals("") ? "0.00" : rows[0][0].ToString().Trim());                            //最小重量
                decimal? end = Convert.ToDecimal(rows[rows.Length - 1][1].ToString().Trim().Equals("") ? "0.00" : rows[rows.Length - 1][1].ToString().Trim());  //最大重量
                
                decimal? minWeight = Convert.ToDecimal(rows[i][0].ToString().Trim().Equals("") ? "0.00" : rows[i][0].ToString().Trim());    //第一列 价格区间起点
                decimal? maxWeight = Convert.ToDecimal(rows[i][1].ToString().Trim().Equals("") ? "0.00" : rows[i][1].ToString().Trim());    //第二列 价格区间终点
                decimal? totalPrice = Convert.ToDecimal(rows[i][2].ToString().Trim().Equals("") ? "0.00" : rows[i][2].ToString().Trim());   //第三列 区间价格
                string type = rows[i][3].ToString().Trim();                                                                                 //第四列 类型
                decimal? unitWeight = Convert.ToDecimal(rows[i][4].ToString().Trim().Equals("") ? "0.00" : rows[i][4].ToString().Trim());   //第五列 单位重量（总乘）
                decimal? unitPrice = Convert.ToDecimal(rows[i][5].ToString().Trim().Equals("") ? "0.00" : rows[i][5].ToString().Trim());    //第六列 单位价格（总乘）

                // 无效重量
                if (weight < Convert.ToDecimal(start) || weight > Convert.ToDecimal(end)) {
                    throw new Exception("该渠道支持的物品重量在【" + start + "KG~" + end + "KG】之间");
                }
                // 最小 < 传入重量 < 最大重量 || 传入重量 = 最大重量
                else if ((weight >= minWeight && weight < maxWeight) || weight == maxWeight)
                {
                    switch (type)
                    {
                        case "速查":
                            //////////////////////////////////////////////////////////////////////////////////////
                            distributor.Price = totalPrice;
                            break;
                        case "总乘":
                            //////////////////////////////////////////////////////////////////////////////////////
                            distributor.Price = (weight / unitWeight) * unitPrice;
                            break;
                        default:
                            throw new Exception("选择了其他渠道：" + type);
                    }
                }
            }
            return distributor;
        }

        //③选择供应商
        private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                List<Distributor> items = this.listView.ItemsSource as List<Distributor>;
                Distributor item = this.listView.SelectedItem as Distributor;

                foreach (Distributor i in items)
                {
                    if (i == item)
                    {
                        i.Flag = 1;
                    }
                    else
                    {
                        i.Flag = 0;
                    }
                }

                this.listView.Items.Refresh();
                SortWindow.distributor = item;
            }
            catch (Exception) {
                MessageBox.Show("选择供应商异常");
            }
        }

        //④打印并处理返回结果
        private void btnPrint_Click(object sender, RoutedEventArgs e)
        {
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //拿到Order+供应商信息后打印
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            try {
                if (order != null && distributor != null)
                {
                    MessageBox.Show("订单：" + order.Cdes + "\n供应商：" + distributor.Name);
                }
            }
            catch (Exception) {
                MessageBox.Show("打印出错");
            }
        }

        //根据运单号查询订单信息
        private Order queryForOrder(string cnum)
        {
            try
            {
                string uri = Config.GetServerURL() + "/order/trans/list";

                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic.Add("caccount", "");
                dic.Add("emskind", "J-NET专线");
                dic.Add("cnum", cnum);
                dic.Add("dateb", "");
                dic.Add("datee", "");

                string json = HttpHelper.GET(uri, dic);

                ResponseRecList<Order> r = JSONHelper.Deserialize<ResponseRecList<Order>>(json);
                if (r.ReturnValue < 0)
                {
                    MessageBox.Show(r.cMess);
                    return null;
                }

                List<Order> list = r.RecList;
                if (list.Count == 0)
                {
                    MessageBox.Show("没有查询到" + cnum);
                    this.txtMess.Text = "等待扫描运单号...";
                    this.txtSZ.Text = "";
                    this.txtOrderInfo.Text = "";
                    this.listView.ItemsSource = null;
                    return null;
                }

                Order item = list[0];
                this.txtMess.Text = "运单号已确认，请在左侧扫码称重...";
                this.txtCnum.Text = item.Cnum;
                this.txtOrderInfo.Text = "客户:" + item.Cunitname
                    + "[" + item.Icid + "]"
                    + "\n业务日期：" + item.Ddate
                    + "\n物品描述：" + item.Cgoods
                    + "\n托运备注：" + item.Ctransnote
                    + "\n数量：" + item.Iquantity
                    + "\n快递类别：" + item.Cemskind
                    + "\n目的地：" + item.Cdes
                    + "\n收件人：" + item.Creceiver;
                this.txtSZ.Focus();
                return item;
            }
            catch (WebException)
            {
                MessageBox.Show("查询异常");
                return null;
            }
        }

    }
}
